package com.chouren.goandroid.ui.view;

import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Shader;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

import com.chouren.goandroid.R;
import com.chouren.goandroid.ui.view.model.DiagramParam;

public class Diagram extends View {
	private List<DiagramParam> dataList;
	private float depth;
	private float spaceLeft;
	private float spaceTop;
	private float margin;
	private float spaceWidth;
	private float maxValue;
	private Paint keyPaint;
	private Paint linePaint;
	private Paint dashLinePaint;
	private Paint brokenLinePaint;
	private Paint dotPaint;
	private Paint framPaint;
	private Bitmap mDot;
	private Path path;

	public Diagram(Context context, List<DiagramParam> dataList) {
		super(context);
		this.dataList = dataList;
		init();
	}
	
	public Diagram(Context context, List<DiagramParam> dataList, float maxValue) {
		super(context);
		this.dataList = dataList;
		this.maxValue = maxValue;
		init();
	}
	
	private void init() {
		if(dataList == null || dataList.size() < 1) return;
		
		int greyColor = 0x5faaaaaa; // 灰色
		int blackColor = 0x5f000000; // 黑色
		int blueColor = 0xff00ffff; // 蓝色
		
		depth = getResources().getDimension(R.dimen.number_depth);
		spaceLeft = 2.0f * depth;
		spaceTop = 2.0f * depth;
		margin = 2.0f * depth;
		spaceWidth = spaceLeft + 0.5f * depth;
		
		keyPaint = new Paint();
		keyPaint.setStrokeWidth(0.1f * depth);
		keyPaint.setTextSize(1.2f * depth);
		keyPaint.setColor(greyColor);
		
		brokenLinePaint = new Paint();
		brokenLinePaint.setStrokeWidth(0.1f * depth);
		brokenLinePaint.setColor(blueColor);
		brokenLinePaint.setAntiAlias(true);
		
		linePaint = new Paint();
		linePaint.setStrokeWidth(0.5f * depth);
		linePaint.setStyle(Style.STROKE);
		linePaint.setColor(blackColor);
		linePaint.setAntiAlias(true);
		
		dashLinePaint = new Paint();
		dashLinePaint.setStyle(Style.STROKE);
		dashLinePaint.setColor(greyColor);
		
		dotPaint = new Paint();
		dotPaint.setStyle(Style.STROKE);
		dotPaint.setColor(greyColor);
		
		framPaint = new Paint();
		framPaint.setAntiAlias(true);
		framPaint.setStrokeWidth(2.0f);
		
		path = new Path();
		mDot = BitmapFactory.decodeResource(getResources(), R.drawable.icon_dot_blue);
		setLayoutParams(new LayoutParams((int) (margin + (int)(spaceWidth + mDot.getWidth()) * dataList.size() + 100), LayoutParams.MATCH_PARENT));
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if(dataList == null || dataList.size() < 1) return;
		
		drawStraightLine(canvas);
		drawKeys(canvas);
		drawBrokenLine(canvas);
	}
	
	private void drawKeys(Canvas canvas) {
		for(int i = 0; i < dataList.size(); i++) {
			String key = dataList.get(i).getKey();
			if(i % 4 == 0)
				canvas.drawText(key, margin + spaceWidth * i, spaceTop - 0.5f * depth, keyPaint);
		}
	}
	
	private void drawStraightLine(Canvas canvas) {
		Path path = new Path();
		for(int i = 0; i < dataList.size(); i++) {
			if(i % 2 == 0) {
				if(i % 4 == 0)
					canvas.drawLine(margin + spaceWidth * i, 0, margin + spaceWidth * i, getHeight() - margin, keyPaint);
				else 
					canvas.drawLine(margin + spaceWidth * i, spaceTop, margin + spaceWidth * i, getHeight() - margin, keyPaint);
			} else {
				path.moveTo(margin + spaceWidth * i, spaceTop);
				path.lineTo(margin + spaceWidth * i, getHeight() - margin);
				PathEffect effects = new DashPathEffect(
						new float[] {depth * 0.3f, depth * 0.3f, depth * 0.3f, depth * 0.3f,}, depth * 0.1f);
				dashLinePaint.setPathEffect(effects);
				canvas.drawPath(path, dashLinePaint);
			}
		}
		path.close();
		canvas.drawLine(margin, getHeight() - margin, (int)spaceWidth * dataList.size() + margin, getHeight() - margin, linePaint);
	}
	
	private void drawBrokenLine(Canvas canvas) {
		Shader mShader = new LinearGradient(0, 0, 0, getHeight(), new int[] {
			Color.argb(100, 0, 255, 255), Color.argb(45, 0, 255, 255),
			Color.argb(10, 0, 255, 255), Color.argb(60, 0, 255, 255) }, 
			null, Shader.TileMode.CLAMP);
		framPaint.setShader(mShader);
		for(int i = 1; i < dataList.size(); i++) {
			float baseStop = dataList.get(i).getValue() * 1.0f / maxValue;
			float stopG = (getHeight() - margin) * (1 - baseStop);
			
			float baseStart = dataList.get(i-1).getValue() * 1.0f / maxValue;
			float gStart = (getHeight() - margin) * (1 - baseStart);
			
			int startX = (int) (margin + spaceWidth * (i - 1));
			int startY = (int) gStart;
			int stopX = (int) (margin + spaceWidth * i);
			int stopY = (int) stopG;
			canvas.drawLine(startX, startY, stopX, stopY, brokenLinePaint);
			
			if(i == 1) canvas.drawBitmap(mDot, startX - mDot.getWidth()/2, startY - mDot.getHeight()/2, null);
			canvas.drawBitmap(mDot, stopX - mDot.getWidth()/2, stopY - mDot.getHeight()/2, null);
			
			path.moveTo(startX, startY);
			path.lineTo(startX, getHeight() - margin);	
			path.lineTo(stopX, getHeight() - margin);
			path.lineTo(stopX, stopY);
			canvas.drawPath(path, framPaint);
		}
		path.close();
	}

	public float getMaxValue() {
		return maxValue;
	}

	public void setMaxValue(float maxValue) {
		this.maxValue = maxValue;
	}
	
}
